package com.zhoug.mpchart.data;

import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.model.GradientColor;
import com.zhoug.mpchart.core.MPBarKey;
import com.zhoug.mpchart.core.MPConstant;
import com.zhoug.mpchart.core.MPEntryList;
import com.zhoug.mpchart.core.styleconfig.IMPBarStyleConfig;
import com.zhoug.mpchart.core.styleconfig.MPBarStyleConfig;
import com.zhoug.mpchart.core.styleconfig.MPChartStyleDefaultUtils;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;

/**
 * 柱状图和数据工厂
 *
 * @Author: zhoug
 * @Date: 2024-02-03
 * @Description:
 */
public class MPBarChartDataCreator {
    private IMPBarStyleConfig styleConfig;
    private List<String> mXLabels = new ArrayList<>();
    private OnDateSetCreateListener<BarDataSet> mOnDateSetCreateListener;
    private ValueFormatter mDataSetValueFormatter;

    public MPBarChartDataCreator() {
        this(new MPBarStyleConfig());
    }

    public MPBarChartDataCreator(IMPBarStyleConfig styleConfig) {
        if (styleConfig != null) {
            this.styleConfig = styleConfig;
        } else {
            this.styleConfig = new MPBarStyleConfig();
        }
    }

    public void setStyleConfig(@NonNull IMPBarStyleConfig styleConfig) {
        this.styleConfig = styleConfig;
    }

    public void setDataSetValueFormatter(ValueFormatter dataSetValueFormatter) {
        this.mDataSetValueFormatter = dataSetValueFormatter;
    }

    public void setOnDateSetCreateListener(OnDateSetCreateListener<BarDataSet> onDateSetCreateListener) {
        this.mOnDateSetCreateListener = onDateSetCreateListener;
    }

    public List<String> getXLabels() {
        return mXLabels;
    }

    public BarData crateBarData(List<HkChartData> list, List<MPBarKey> mpBarKeys) {
        return crateBarData(list,mpBarKeys,MPConstant.LEFT);
    }

    public BarData crateBarData(List<HkChartData> list, List<MPBarKey> mpBarKeys,@MPConstant.AxisDependency int axisDependency) {
        //x轴名称
        if (mXLabels == null) {
            mXLabels = new ArrayList<>();
        } else {
            mXLabels.clear();
        }
        if (list != null && list.size() > 0) {
            if (mpBarKeys == null || mpBarKeys.size() == 0) {
                mpBarKeys = createMPBarKey(list,axisDependency);
            }
            if (mpBarKeys == null || mpBarKeys.size() == 0) {
                return null;
            }
            List<MPEntryList<BarEntry>> barEntries = new ArrayList<>();   //柱状图
            for (MPBarKey mpBarKey : mpBarKeys) {
                barEntries.add(new MPEntryList<>(mpBarKey.getKeys(), mpBarKey.getAxisDependency()));
            }
            for (int i = 0; i < list.size(); i++) {
                int x = i + 1;
                HkChartData hkChartData = list.get(i);
                String name = hkChartData.getName();
                mXLabels.add(name);
                //柱状图BarEntry
                initMPEntryList(barEntries, x, hkChartData);
            }
            //柱状图
            return createBarData(barEntries);
        }
        return null;
    }

    /**
     * 根据配置创建默认的 List<MPBarLineKey>
     *
     * @param list
     * @return
     */
    protected List<MPBarKey> createMPBarKey(List<HkChartData> list) {
      return createMPBarKey(list,MPConstant.LEFT);
    }

    /**
     * 根据配置创建默认的 List<MPBarLineKey>
     *
     * @param list
     * @return
     */
    protected List<MPBarKey> createMPBarKey(List<HkChartData> list,@MPConstant.AxisDependency int axisDependency) {
        String[] keys = HkChartData.getKeys(list);
        if (keys != null && keys.length > 0) {
            List<MPBarKey> result = new ArrayList<>();
            if (styleConfig.isStackBar()) {
                result.add(new MPBarKey(keys,axisDependency));
            } else {
                for (String key : keys) {
                    result.add(new MPBarKey(new String[]{key},axisDependency));
                }
            }
            return result;
        }
        return null;
    }

    /**
     * 使用 HkChartData 初始化MPEntryList中的entries
     *
     * @param barEntries
     * @param x
     * @param hkChartData
     */
    public static void initMPEntryList(List<MPEntryList<BarEntry>> barEntries, float x, HkChartData hkChartData) {
        if (barEntries == null || barEntries.isEmpty() || hkChartData == null) return;
        for (MPEntryList<BarEntry> item : barEntries) {
            String[] keys = item.getKeys();
            if (keys.length > 1) {
                float[] yValues = new float[keys.length];
                for (int j = 0; j < keys.length; j++) {
                    yValues[j] = hkChartData.getValue(keys[j]);
                }
                item.addEntry(new BarEntry(x, yValues, hkChartData));
            } else {
                item.addEntry(new BarEntry(x, hkChartData.getValue(keys[0]), hkChartData));
            }
        }
    }

    /**
     * 创建BarData
     *
     * @param barEntries
     * @return
     */
    public BarData createBarData(List<MPEntryList<BarEntry>> barEntries) {
        if (barEntries == null || barEntries.size() == 0) return null;
        List<IBarDataSet> dataSets = new ArrayList<>();
        for (int i = 0; i < barEntries.size(); i++) {
            MPEntryList<BarEntry> mpEntryList = barEntries.get(i);
            String[] keys = mpEntryList.getKeys();
            BarDataSet barDataSet;
            if (keys.length > 1) {
                barDataSet = new BarDataSet(mpEntryList.getEntries(), null);
                barDataSet.setStackLabels(keys);
                int[] colors = new int[keys.length];
                List<GradientColor> gradientColors = null;
                //渐变色
                if (styleConfig.getGradientColors() != null && styleConfig.getGradientColors().size() > 0) {
                    gradientColors = new ArrayList<>();
                    for (int j = 0; j < keys.length; j++) {
                        GradientColor barGradientColor = styleConfig.getBarGradientColor(j);
                        gradientColors.add(barGradientColor);
                        colors[j] = barGradientColor.getStartColor();
                    }
                } else {
                    //纯色
                    for (int j = 0; j < colors.length; j++) {
                        colors[j] = styleConfig.getBarColor(j);
                    }
                }
                barDataSet.setColors(colors);
                barDataSet.setGradientColors(gradientColors);
            } else {
                barDataSet = new BarDataSet(mpEntryList.getEntries(), keys[0]);
                GradientColor barGradientColor = styleConfig.getBarGradientColor(i);
                if (barGradientColor != null) {
                    barDataSet.setGradientColor(barGradientColor.getStartColor(), barGradientColor.getEndColor());
                    barDataSet.setColor(barGradientColor.getStartColor());
                } else {
                    barDataSet.setColor(styleConfig.getBarColor(i));
                }

            }
            if (mpEntryList.getAxisDependency() == MPConstant.RIGHT) {
                barDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
            } else {
                barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
            }
            barDataSet.setValueFormatter(mDataSetValueFormatter);
            MPChartStyleDefaultUtils.initBarDataSet(barDataSet);
            if (mOnDateSetCreateListener != null) {
                mOnDateSetCreateListener.onInitDataSetStyle(barDataSet, i);
            }

            dataSets.add(barDataSet);
        }
        return new BarData(dataSets);
    }


}
